package com.ptswitch.material.service.impl;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.tapestry5.ioc.annotations.Inject;

import com.ptswitch.material.model.common.Uzer;
import com.ptswitch.material.model.security.Permission;
import com.ptswitch.material.model.security.Role;
import com.ptswitch.material.service.UserService;

public class ShiroRealmImpl extends AuthorizingRealm {
    @Inject
    private UserService userSer;

    public ShiroRealmImpl() {
        setName("jdbcRealm");//This name must match the name in the User class's getPrincipals() method
    }

    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

        UsernamePasswordToken upToken = (UsernamePasswordToken) token;
        String username = upToken.getUsername();
        String password = new String(upToken.getPassword());
        Uzer user = userSer.findByUsernameAndPassword(username, password);
        if (user == null) {
            return null;
        }
        AuthenticationInfo info = new SimpleAuthenticationInfo(username, upToken.getPassword(), getName());

        return info;
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

        if (principals == null) {
            throw new AuthorizationException("PrincipalCollection method argument cannot be null.");
        }

        String username = (String) getAvailablePrincipal(principals);
        Uzer user = userSer.findByUsername(username);
        if (user == null) {
            return null;
        }

        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        for (Role role : user.getRoles()) {
            info.addRole(role.getRoleName());
            for (Permission permission : role.getPermissions()) {
                info.addStringPermission(permission.getPermissionName());
            }
        }
        return info;

    }

}
